package org.aldar.bquest.profile;

import org.aldar.bquest.logic.GameTutorial;
import org.aldar.bquest.logic.controller.level.LevelDef;
import org.aldar.bquest.logic.controller.level.LevelDefinition;
import org.aldar.bquest.screens.MainBoardScreen;
import org.aldar.bquest.util.Logger;
import org.aldar.bquest.util.SQLiteHelper;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * User: Daria
 * Date: 2/3/14 9:59 PM
 */
public class GameProfile {

    private static final boolean allAreasUnlocked = false;
    private static final boolean allLevelsFinishedForTest = false;

    private static final String DB_TOTAL_FAME_KEY = "totalFame";
    private static Logger LOG = new Logger(GameProfile.class);

    private static final String DB_FINISHED_LEVELS_KEY = "finishedLevels";
    private static final String DB_TOTAL_POINTS_KEY = "totalPoints";
    private static final String DB_LAST_UNLOCKED_AREA_INDEX_KEY = "lastAreaUnlocked";
    private static final String DB_SETTING_SOUNDS = "settingsPlaySounds";
    private static final String DB_SETTING_MUSIC = "settingsPlayMusic";

    private static LevelProfile currentLevelProfile;

    private static LevelDef currentLevel;

    private static int lastUnlockedLevelNumber;

    private static GameTutorial tutorial;

    public static Integer selectedLevelIndex;
    public static Integer selectedLevelAreaIndex;

    private static Integer totalAchievedPoints = null;
    private static Integer totalFame = null;

    private static String language = "ru";

    private static Boolean settingsPlaySounds = null; //default value
    private static Boolean settingsPlayMusic = null; //default value


    public static Integer getTotalAchievedPoints(SQLiteHelper helper) {
        String totalPointsStr = helper.queryData().get(DB_TOTAL_POINTS_KEY);
        if (totalPointsStr != null) {
            totalAchievedPoints = Integer.valueOf(totalPointsStr);
        } else {
            totalAchievedPoints = 0;
        }
        return totalAchievedPoints;
    }

    public static boolean getSettingsPlaySounds(SQLiteHelper helper) {
        if (settingsPlaySounds != null) {
            return settingsPlaySounds;
        }
        Boolean playSoundsSaved = getBooleanValueFromDb(DB_SETTING_SOUNDS, helper);
        if (playSoundsSaved != null) {
            settingsPlaySounds = playSoundsSaved;
        } else {
            settingsPlaySounds = true; //default value
        }
        return settingsPlaySounds;
    }

    public static void setSettingsPlaySound(boolean valueToSave, SQLiteHelper helper) {
        settingsPlaySounds = valueToSave;
        helper.insertOrUpdateValue(DB_SETTING_SOUNDS, String.valueOf(settingsPlaySounds));
    }

    public static boolean getSettingsPlayMusic(SQLiteHelper helper) {
        if (settingsPlayMusic != null) {
            return settingsPlayMusic;
        }
        Boolean playMusicSaved = getBooleanValueFromDb(DB_SETTING_MUSIC, helper);
        if (playMusicSaved != null) {
            settingsPlayMusic = playMusicSaved;
        } else {
            settingsPlayMusic = true;
        }
        return settingsPlayMusic;
    }

    public static void setSettingsPlayMusic(boolean valueToSave, SQLiteHelper helper) {
        settingsPlayMusic = valueToSave;
        helper.insertOrUpdateValue(DB_SETTING_MUSIC, String.valueOf(settingsPlayMusic));
        if (settingsPlayMusic == false) {

        }
    }

    private static Boolean getBooleanValueFromDb(String key, SQLiteHelper helper) {
        String booleanStr = helper.queryData().get(key);
        if (booleanStr == null) {
            return null;
        }
        return Boolean.parseBoolean(booleanStr);
    }

    public static void setTotalAchievedPoints(Integer totalAchievedPoints, SQLiteHelper helper) {
        GameProfile.totalAchievedPoints = totalAchievedPoints;
        helper.insertOrUpdateValue(DB_TOTAL_POINTS_KEY, totalAchievedPoints.toString());
    }

    public static Integer getTotalFame(SQLiteHelper helper) {
        String totalPointsStr = helper.queryData().get(DB_TOTAL_FAME_KEY);
        if (totalPointsStr != null) {
            totalFame = Integer.valueOf(totalPointsStr);
        } else {
            totalFame = 0;
        }
        return totalFame;
    }

    public static void setTotalFame(Integer totalFame, SQLiteHelper helper) {
        GameProfile.totalFame = totalFame;
        helper.insertOrUpdateValue(DB_TOTAL_FAME_KEY, totalFame.toString());
    }

    public static void setLastUnlockedAreaIndex(Integer lastUnlockedAreaIndex, SQLiteHelper helper) {
        helper.insertOrUpdateValue(DB_LAST_UNLOCKED_AREA_INDEX_KEY, lastUnlockedAreaIndex.toString());
    }

    public static Integer getLastUnlockedAreaIndex(SQLiteHelper helper) {
        if (allAreasUnlocked) {
            return LevelDefinition.getLevels().length - 1;
        }
        String index = helper.queryData().get(DB_LAST_UNLOCKED_AREA_INDEX_KEY);
        if (index != null) {
            return Integer.valueOf(index);
        } else {
            return 0;
        }
    }


    public static void initGameProfile(SQLiteHelper mSQLiteHelper) {
        tutorial = new GameTutorial(mSQLiteHelper);
    }


    public static LevelProfile getCurrentLevelProfile() {
        return currentLevelProfile;
    }

    public static void setCurrentLevelProfile(LevelProfile currentLevelProfile) {
        GameProfile.currentLevelProfile = currentLevelProfile;
    }

    public static LevelDef getCurrentLevel() {
        return currentLevel;
    }

    public static void setCurrentLevel(LevelDef currentLevel) {
        GameProfile.currentLevel = currentLevel;
    }

    public static GameTutorial getTutorial(SQLiteHelper sqLiteHelper) {
        if (tutorial == null) {
            tutorial = new GameTutorial(sqLiteHelper);
        }
        return tutorial;
    }

    public static Map<Integer, Integer[]> getAllFinishedLevels(SQLiteHelper mSQLiteHelper) {
        Map<Integer, Integer[]> levelData = mSQLiteHelper.queryLevelData();
        LOG.i("All finished levels string in DB = " + levelData.size());
        return levelData;
    }

    public static Map<Integer, Integer[]> getAllFinishedLevelsForArea(int areaIndex, SQLiteHelper mSQLiteHelper) {
        Map<Integer, Integer[]> levelData = mSQLiteHelper.queryLevelData();
        Set<Integer> finishedLevelKeys = levelData.keySet();
        Map<Integer, Integer[]> result = new HashMap<Integer, Integer[]>();
        if (allLevelsFinishedForTest) {
            for (int j = 0; j < 6; j++) {
                result.put(j, new Integer[]{0, 0});
            }
            return result;
        }
        for (Integer key : finishedLevelKeys) {
            int[] levelKeyValues = retrieveLevelKeyValues(key);
            if (levelKeyValues[0] == areaIndex) {
                result.put(levelKeyValues[1], levelData.get(key));
            }
        }
        return result;
    }

    private static int[] retrieveLevelKeyValues(Integer key) {
        int[] result = new int[2];
        result[0] = key / 10;
        result[1] = key - result[0] * 10;
        return result;
    }

    public static void saveFinishedLevels(Map<Integer, Integer> levelData) {
        LOG.i("Saving finished levels = " + levelData);
        MainBoardScreen.getmSQLiteHelper().saveLevelData(levelData);
    }


    public static void eraseSavedGame(SQLiteHelper sqLiteHelper) {
        sqLiteHelper.resetLevelData();
        //sqLiteHelper.deleteValue(DB_LAST_UNLOCKED_AREA_INDEX_KEY);
        //sqLiteHelper.deleteValue(DB_TOTAL_POINTS_KEY);
        //sqLiteHelper.deleteValue(DB_TOTAL_FAME_KEY);
        sqLiteHelper.insertOrUpdateValue(DB_LAST_UNLOCKED_AREA_INDEX_KEY, "0");
        sqLiteHelper.insertOrUpdateValue(DB_TOTAL_POINTS_KEY, "0");
        sqLiteHelper.insertOrUpdateValue(DB_TOTAL_FAME_KEY, "0");
        GameTutorial.eraseDbState(sqLiteHelper);
    }

    public static String getLanguage() {
        return language;
    }

    public static void saveFinishedLevel(Integer levelKey, int levelScoreToSave, int levelFameToSave, SQLiteHelper sqLiteHelper) {
        sqLiteHelper.saveLevelData(levelKey, levelScoreToSave, levelFameToSave);
    }

    public static boolean isLevelAlreadyOpened(int areaIndex, int levelIndex, SQLiteHelper sqLiteHelper) {
        String levelKey = areaIndex + "_" + levelIndex + "_opened";
        Boolean value = getBooleanValueFromDb(levelKey, sqLiteHelper);
        if (value != null && Boolean.TRUE.equals(value)) {
            return true;
        } else {
            return false;
        }
    }

    public static void setLevelAlreadyOpened(int areaIndex, int levelIndex, SQLiteHelper sqLiteHelper) {
        String levelKey = areaIndex + "_" + levelIndex + "_opened";
        sqLiteHelper.insertOrUpdateValue(levelKey, "true");
    }
}
